﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using SqlSugar;
using WomanMotion.WebApi.Infrastructure.DataBaseCommon;
using WomanMotion.WebApi.Infrastructure.Ioc;

namespace WomanMotion.WebApi.Service.IService
{
    /// <summary>
    /// 带增删改查的基类接口
    /// </summary>
    /// <typeparam name="TEntity">数据库实体</typeparam>
    /// <typeparam name="TVM">前端返回VM</typeparam>
    /// <typeparam name="TUpdataDTO">更新数据DTO</typeparam>
    /// <typeparam name="TCreatedDTO">添加数据DTO</typeparam>
    public interface IBaseCRUDService<TEntity, TVM, TUpdataDTO, TCreatedDTO> : IBaseService where TEntity : class
    {
        #region 添加

        /// <summary>
        /// 添加一条数据(异步)
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns></returns>
        Task<TVM> CreatedAsync(TCreatedDTO dto);

        /// <summary>
        /// 添加一条数据,传入一个表达式判断数据是否存在，如果存在就返回原有数据，不存在就新增(异步)
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        Task<TVM> CreatedAsync(TCreatedDTO dto, Expression<Func<TEntity, bool>> expression);

        #endregion 添加

        #region 删除

        /// <summary>
        /// 根据主键删除数据(异步)
        /// </summary>
        /// <param name="id">主键ID</param>
        /// <returns></returns>
        Task<int> DeleteAsync(object id);

        /// <summary>
        /// 根据主键数组批量删除数据(异步)
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        Task<int> DeleteAsync(object[] ids);

        /// <summary>
        /// 根据条件删除数据(异步)
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        Task<int> DeleteAsync(Expression<Func<TEntity, bool>> expression);

        #endregion 删除

        #region 更新

        /// <summary>
        /// 启用或禁用单条数据(异步)
        /// </summary>
        /// <param name="ifdb">禁用还是启用</param>
        /// <param name="id">主键id</param>
        /// <returns>影响行数</returns>
        Task<int> UpdateDisableAsync(DisableEnum ifdb, long id);

        /// <summary>
        /// 启用或禁用多条数据(异步)
        /// </summary>
        /// <param name="ifdb">禁用还是启用</param>
        /// <param name="id">主键id</param>
        /// <returns>影响行数</returns>
        Task<int> UpdateDisableAsync(DisableEnum ifdb, long[] id);

        /// <summary>
        /// 更新单条数据(异步)
        /// </summary>
        /// <param name="entity">需要更新的实体</param>
        /// <returns>影响行数</returns>
        Task<TVM> UpdateAsync(TUpdataDTO dto);

        /// <summary>
        /// 更新单条数据传入实体更新实体(异步)
        /// </summary>
        /// <param name="entity">需要更新的实体</param>
        /// <returns>影响行数</returns>
        Task<TEntity> UpdateEntityAsync(TEntity entity);

        /// <summary>
        /// 批量更新数据(异步)
        /// </summary>
        /// <param name="dto">实体集合</param>
        /// <returns>实体</returns>
        Task<List<TVM>> UpdateAsync(List<TUpdataDTO> dto);

        #endregion 更新

        #region 查询

        /// <summary>
        /// 查询单个数据(异步)
        /// </summary>
        /// <param name="expression">条件</param>
        /// <returns></returns>
        Task<TVM> GetAsync(Expression<Func<TEntity, bool>> expression);

        /// <summary>
        /// 查询单个数据,返回实体(异步)
        /// </summary>
        /// <param name="expression">条件</param>
        /// <returns></returns>
        Task<TEntity> GetEntityAsync(Expression<Func<TEntity, bool>> expression);

        /// <summary>
        /// 查询单个带导航数据(异步)
        /// </summary>
        /// <param name="expression">条件</param>
        /// <param name="ignoreProperyNameList">需要忽略的导航属性</param>
        /// <returns></returns>
        Task<TVM> GetNavAsync(Expression<Func<TEntity, bool>> expression, params string[] ignoreProperyNameList);

        /// <summary>
        /// 查询单个数据(同步)
        /// </summary>
        /// <param name="expression">条件</param>
        /// <returns></returns>
        TVM Get(Expression<Func<TEntity, bool>> expression);

        /// <summary>
        ///查询单个带导航数据(同步)
        /// </summary>
        /// <param name="expression">条件</param>
        /// <param name="ignoreProperyNameList">需要忽略的导航属性</param>
        /// <returns></returns>
        TVM GetNav(Expression<Func<TEntity, bool>> expression, params string[] ignoreProperyNameList);

        /// <summary>
        /// 查询所有数据集合(异步)
        /// </summary>
        /// <returns></returns>
        Task<List<TVM>> GetListAsync();

        /// <summary>
        /// 查询所有带排序数据集合(异步)
        /// </summary>
        /// <param name="orderby">排序数组字符串</param>
        /// <returns></returns>
        Task<List<TVM>> GetListOrderByAsync(string[] orderby);

        /// <summary>
        /// 查询所有带导航数据集合(异步)
        /// </summary>
        /// <param name="ignoreProperyNameList">需要忽略的导航属性</param>
        /// <returns></returns>
        Task<List<TVM>> GetListNavAsync(params string[] ignoreProperyNameList);

        /// <summary>
        /// 查询所有带排序带导航数据集合(异步)
        /// </summary>
        /// <param name="orderby">排序数组字符串</param>
        /// <param name="ignoreProperyNameList">需要忽略的导航属性</param>
        /// <returns></returns>
        Task<List<TVM>> GetListNavOrderByAsync(string[] orderby, params string[] ignoreProperyNameList);

        /// <summary>
        /// 根据主键查询单个数据(异步)
        /// </summary>
        /// <param name="id">id主键</param>
        /// <returns>实体</returns>
        Task<TVM> GetByIdAsync(object id);

        /// <summary>
        ///根据主键查询单个带导航数据(异步)
        /// </summary>
        /// <param name="id">id主键</param>
        /// <param name="ignoreProperyNameList">需要忽略的导航属性</param>
        /// <returns></returns>
        Task<TVM> GetByIDNavAsync(object id, params string[] ignoreProperyNameList);

        /// <summary>
        /// 根据主键查询单个数据(同步)
        /// </summary>
        /// <param name="id">id主键</param>
        /// <returns></returns>
        TVM GetById(long id);

        /// <summary>
        ///根据主键查询单个带导航数据(同步)
        /// </summary>
        /// <param name="id">id主键</param>
        /// <param name="ignoreProperyNameList">需要忽略的导航属性</param>
        /// <returns></returns>
        TVM GetByIDNav(object id, params string[] ignoreProperyNameList);

        /// <summary>
        /// 按条件返回数据集合(异步)
        /// </summary>
        /// <param name="expression">条件</param>
        /// <returns></returns>
        Task<List<TVM>> GetListAsync(Expression<Func<TEntity, bool>> expression);

        /// <summary>
        ///按条件返回带排序数据集合(异步)
        /// </summary>
        /// <param name="expression">条件</param>
        /// <param name="orderby">排序数组字符串</param>
        /// <returns></returns>
        Task<List<TVM>> GetListOrderByAsync(Expression<Func<TEntity, bool>> expression, string[] orderby);

        /// <summary>
        ///按条件返回带导航数据集合(异步)
        /// </summary>
        /// <param name="expression">条件</param>
        /// <param name="ignoreProperyNameList">需要忽略的导航属性</param>
        /// <returns></returns>

        Task<List<TVM>> GetListNavAsync(Expression<Func<TEntity, bool>> expression, params string[] ignoreProperyNameList);

        /// <summary>
        ///按条件返回带排序带导航数据集合(异步)
        /// </summary>
        /// <param name="expression"条件></param>
        /// <param name="orderby">排序数组字符串</param>
        /// <param name="ignoreProperyNameList">需要忽略的导航属性</param>
        /// <returns></returns>

        Task<List<TVM>> GetListNavOrderByAsync(Expression<Func<TEntity, bool>> expression, string[] orderby, params string[] ignoreProperyNameList);

        /// <summary>
        /// 查询是否有符合记录的数据存在(异步)
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns>存在true,不存在false</returns>
        Task<bool> GetAnyAsync(Expression<Func<TEntity, bool>> expression);

        /// <summary>
        /// 查询存在数据的行数(异步)
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns>数据行数</returns>
        Task<int> GetCountAsync(Expression<Func<TEntity, bool>> expression);

        /// <summary>
        /// 分页查询单表数据(异步)
        /// </summary>
        /// <param name="pars">查询参数</param>
        /// <returns>通用返回结果</returns>
        Task<PageViewBase<List<TVM>>> GetPageListAsync(QueryParameterBase pars);

        /// <summary>
        ///分页查询带导航单表数据(异步)
        /// </summary>
        /// <param name="pars">查询参数</param>
        /// <param name="ignoreProperyNameList">需要忽略的导航属性</param>
        /// <returns></returns>
        Task<PageViewBase<List<TVM>>> GetPageNavListAsync(QueryParameterBase pars, params string[] ignoreProperyNameList);

        /// <summary>
        ///分页获取实体数据的KeyValuePair(异步)
        /// </summary>
        /// <param name="pars">分页查询对象</param>
        /// <returns>key是数据总数,value是数据集合</returns>
        Task<KeyValuePair<int, List<TVM>>> GetPageKeyValuePairListAsync(QueryParameterBase pars);

        /// <summary>
        ///分页获取带导航实体数据的KeyValuePair(异步)
        /// </summary>
        /// <param name="pars">分页查询对象</param>
        /// <param name="ignoreProperyNameList">需要忽略的导航属性</param>
        /// <returns></returns>
        Task<KeyValuePair<int, List<TVM>>> GetPageNavKeyValuePairListAsync(QueryParameterBase pars, params string[] ignoreProperyNameList);

        #endregion 查询
    }
}